home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 5 / MACVOGL- / SUN.C < prev    next >
Text File  |  1992-07-19  |  14KB  |  765 lines

  1.  
  2. /*
  3.  * Vogle driver for Sun using sunview.
  4.  *
  5.  */
  6. #include <stdio.h>
  7.  
  8. #include <suntool/sunview.h>
  9. #include <fcntl.h>
  10. #include <errno.h>
  11.  
  12. #ifdef SUN_3_5
  13. #define event_action    event_id
  14. #endif
  15.  
  16. #include "vogl.h"
  17.  
  18. #define STDMAPSIZE    16    /* map that can be used with buffering */
  19. #define    CMAPSIZE    256
  20. #define    STDFONTDIR    "/usr/lib/fonts/fixedwidthfonts/"
  21.  
  22. #define MIN(x,y)    ((x) < (y) ? (x) : (y))
  23. #define COL(c)        ((usememory) ? (c) : (c) | ((c << 4)))
  24.  
  25. #define OP_WHITE    (PIX_SRC | PIX_COLOR(COL(7)) | PIX_DONTCLIP)
  26. #define OP_BLACK    (PIX_SRC | PIX_COLOR(COL(0)) | PIX_DONTCLIP)
  27. #define COL_WHITE    COL(7)
  28. #define COL_BLACK    COL(0)
  29.  
  30. static Pixwin    *pw_tmp, *pw;
  31.  
  32. #ifdef BASE_COL_SET
  33. static Pixwin    *pw0;
  34. #endif
  35.  
  36. static Pixrect    *frontb, *backb;
  37. static Pixfont    *font_id;
  38. static int    inbackb;
  39. static int    wfd, blanket_win;
  40. static int    oldflags;
  41. static int    pwfd, h, w;
  42. static int    colour, usememory, fmask, bmask, shift;
  43. static u_char    fr[CMAPSIZE], fg[CMAPSIZE], fb[CMAPSIZE];
  44. static u_char    br[CMAPSIZE], bg[CMAPSIZE], bb[CMAPSIZE];
  45. static u_char    *red, *green, *blue;
  46.  
  47. /*
  48.  * default colour map
  49.  */
  50. static u_char    defred[STDMAPSIZE] = {
  51.             0, 255, 0, 255, 0, 255, 0, 255, 0,
  52.         },
  53.         defgreen[STDMAPSIZE] = {
  54.             0, 0, 255, 255, 0, 0, 255, 255, 0,
  55.         },
  56.         defblue[STDMAPSIZE] = {
  57.             0, 0, 0, 0, 255, 255, 255, 255, 0,
  58.         };
  59.  
  60. /*
  61.  * redisplay
  62.  *
  63.  *    redisplay the window.
  64.  */
  65. static void
  66. redisplay()
  67. {
  68.     pw_damaged(pw);
  69.  
  70.     pw_repairretained(pw);
  71.  
  72.     pw_donedamaged(pw);
  73. }
  74.  
  75. /*
  76.  * SUN_init
  77.  *
  78.  *    initialises drawing canvas to occupy current window
  79.  */
  80. SUN_init()
  81. {
  82.     int        i, prefx, prefy, prefxs, prefys, bw;
  83.     char        name[WIN_NAMESIZE];
  84.     Inputmask    imk, imp;
  85.     Rect        rect;
  86.     int        rootfd;
  87.  
  88.     pw = (Pixwin *)NULL;
  89.  
  90. #ifdef BASE_COL_SET
  91.     pw0 = pw;
  92. #endif
  93.  
  94.     /*
  95.      * get the gfx win so we have some default sizes to use
  96.      */
  97.     we_getgfxwindow(name);
  98.     pwfd = open(name, 2);
  99.     win_getrect(pwfd, &rect);
  100.     
  101.         /*
  102.          * Get the input masks of the base window...
  103.          */
  104.         win_get_pick_mask(pwfd, &imp);
  105.         win_get_kbd_mask(pwfd, &imk);
  106.  
  107.  
  108.     /*
  109.      * get a new window (either going to be a blanket window or
  110.      * a window in it's own right)
  111.      */
  112.     if ((wfd = win_getnewwindow()) == -1) {
  113.         fprintf(stderr, "No new windows!\n");
  114.         exit(1);
  115.     }
  116.  
  117.     getprefposandsize(&prefx, &prefy, &prefxs, &prefys);
  118.  
  119.     if (prefx > -1) {
  120.         rect.r_left = prefx;
  121.         rect.r_top = prefy;
  122.     }
  123.  
  124.     if (prefxs > -1) {
  125.         rect.r_width = prefxs;
  126.         rect.r_height = prefys;
  127.     }
  128.  
  129.     w = rect.r_width;
  130.     h = rect.r_height;
  131.  
  132.     bw = 3;
  133.     if (prefx > -1 || prefxs > -1) {
  134.         /*
  135.          * Make room for a 3 pixel border
  136.          */
  137.         if (rect.r_left <= 2)
  138.             rect.r_left = 0;
  139.         else
  140.             rect.r_left -= bw;
  141.  
  142.         if (rect.r_top <= 2)
  143.             rect.r_top = 0;
  144.         else
  145.             rect.r_top -= bw;
  146.  
  147.         rect.r_width += 2 * bw;
  148.         rect.r_height += 2 * bw;
  149.  
  150.         win_setrect(wfd, &rect);
  151.  
  152.         /*
  153.          * get the parent (probably full screen window)
  154.          * so we can size our window to any size we like
  155.          * on the screen.
  156.          */
  157.         we_getparentwindow(name);
  158.         rootfd = open(name, 2);
  159.  
  160.         win_setlink(wfd, WL_PARENT, win_fdtonumber(rootfd));
  161.         win_setlink(wfd, WL_COVERED, WIN_NULLLINK);
  162.         win_insert(wfd);
  163.  
  164.         wmgr_top(wfd, rootfd);
  165.  
  166.         pw = pw_open(wfd);
  167.  
  168. #ifdef BASE_COL_SET
  169.         /*
  170.          * Get the pixrect for the window that we started in
  171.          * so we can set it's colourmap as well
  172.          */
  173.         pw0 = pw_open(pwfd);
  174. #endif
  175.  
  176.         close(rootfd);
  177.         blanket_win = 0;
  178.     } else {
  179.         win_insertblanket(wfd, pwfd);
  180.         pw = pw_region(pw_open(wfd), 0, 0, w, h);
  181.         blanket_win = 1;
  182.     }
  183.  
  184.     /*
  185.      * Set non-blocking input for window.
  186.      */
  187.     oldflags = fcntl(wfd, F_GETFL, 0);
  188.     if (fcntl(wfd, F_SETFL, FNDELAY) < 0) {
  189.         perror("F_SETFL");
  190.         exit(1);
  191.     }
  192.  
  193.     /*
  194.      * Setup the input masks for window.
  195.      */
  196.  
  197.     win_set_kbd_mask(wfd, &imk);
  198.         win_set_pick_mask(wfd, &imp);
  199.  
  200.     vdevice.depth = pw->pw_pixrect->pr_depth;
  201.  
  202.     /* 
  203.      *  Set up the color map.  
  204.      */
  205.  
  206.     for (i = 0; i < CMAPSIZE; i++) {
  207.         fr[i] = defred[i & 0x0f];
  208.         fg[i] = defgreen[i & 0x0f];
  209.         fb[i] = defblue[i & 0x0f];
  210.  
  211.         br[i] = defred[(i & 0xf0) >> 4];
  212.         bg[i] = defgreen[(i & 0xf0) >> 4];
  213.         bb[i] = defblue[(i & 0xf0) >> 4];
  214.     }
  215.  
  216.     fr[255] = fg[255] = fb[255] = 255;
  217.     br[255] = bg[255] = bb[255] = 255;
  218.  
  219.     red = fr;
  220.     green = fg;
  221.     blue = fb;
  222.  
  223.     if (vdevice.depth > 1) {
  224.         pw_setcmsname(pw, "vogl");
  225.         pw_putcolormap(pw, 0, CMAPSIZE, fr, fg, fb);
  226. #ifdef BASE_COL_SET
  227.         if (pw0 != (Pixwin *)NULL) {
  228.             pw_setcmsname(pw0, "vogl");
  229.             pw_putcolormap(pw0, 0, CMAPSIZE, fr, fg, fb);
  230.         }
  231. #endif
  232.     }
  233.  
  234.     if (prefx > -1 || prefxs > -1) {
  235.         /*
  236.          * Draw the border...
  237.          */
  238.         int    x0, y0, x1, y1;
  239.  
  240.         x0 = y0 = 0;
  241.         x1 = rect.r_width - 1;
  242.         y1 = 0;
  243.         pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
  244.         pw_vector(pw, x0 + 2, y0 + 2, x1 - 2, y1 + 2, OP_WHITE, COL_WHITE);
  245.         pw_vector(pw, x0 + 1, y0 + 1, x1 - 1, y1 + 1, OP_BLACK, COL_BLACK);
  246.         x0 = x1;
  247.         y0 = y1;
  248.         x1 = x0;
  249.         y1 = rect.r_height - 1;
  250.         pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
  251.         pw_vector(pw, x0 - 2, y0 + 2, x1 - 2, y1 - 2, OP_WHITE, COL_WHITE);
  252.         pw_vector(pw, x0 - 1, y0 + 1, x1 - 1, y1 - 1, OP_BLACK, COL_BLACK);
  253.         x0 = x1;
  254.         y0 = y1;
  255.         x1 = 0;
  256.         y1 = rect.r_height - 1;
  257.         pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
  258.         pw_vector(pw, x0 - 2, y0 - 2, x1 + 2, y1 - 2, OP_WHITE, COL_WHITE);
  259.         pw_vector(pw, x0 - 1, y0 - 1, x1 + 1, y1 - 1, OP_BLACK, COL_BLACK);
  260.         x0 = x1;
  261.         y0 = y1;
  262.         x1 = 0;
  263.         y1 = 0;
  264.         pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
  265.         pw_vector(pw, x0 + 2, y0 - 2, x1 + 2, y1 + 2, OP_WHITE, COL_WHITE);
  266.         pw_vector(pw, x0 + 1, y0 - 1, x1 + 1, y1 + 1, OP_BLACK, COL_BLACK);
  267.  
  268.         pw_tmp = pw;
  269.         pw = pw_region(pw_tmp, 3, 3, w, h);
  270.         pw_close(pw_tmp);
  271.     }
  272.  
  273.  
  274.     frontb = pw->pw_prretained = mem_create(w, h, vdevice.depth);
  275.     backb = (Pixrect *)NULL;
  276.  
  277.     fmask = 0xf0;
  278.     bmask = 0x0f;
  279.  
  280.     signal(SIGWINCH, redisplay);
  281.  
  282.     /*
  283.      *  Let VOGLE know about the window size.
  284.      */
  285.         vdevice.sizeX = vdevice.sizeY = MIN(w, h);
  286.     vdevice.sizeSx = w;
  287.     vdevice.sizeSy = h;
  288.  
  289.     return(1);
  290. }
  291.  
  292. /*
  293.  * SUN_exit
  294.  *
  295.  *    cleans up before returning the window to normal.
  296.  */
  297. SUN_exit()
  298. {
  299.     long    nbytes;
  300.     int    i;
  301.     Event    event;
  302.  
  303.     /*
  304.      * Flush all events for this window.
  305.      *
  306.      * While doing non-blocking input input_readevent returns -1 and
  307.      * errno == EWOULDBLOCK when everything has been read, so if 
  308.      * errno != EWOULDBLOCK then something naughty happened...
  309.      */
  310.     while (input_readevent(wfd, &event) >= 0)
  311.         ;
  312.  
  313.     if (errno != EWOULDBLOCK) {
  314.         perror("SUN_exit(flushing), input_readevent");
  315.         exit();
  316.     }
  317.  
  318.     /*
  319.      * reset wfd to blocking input.
  320.      */
  321.     if (fcntl(wfd, F_SETFL, oldflags) < 0) {
  322.         perror("oldflags, F_SETFL");
  323.         exit(1);
  324.     }
  325.  
  326.     if (blanket_win)
  327.         win_removeblanket(wfd);
  328.     else 
  329.         win_remove(wfd);
  330.  
  331.     signal(SIGWINCH, SIG_DFL);
  332.  
  333.     return(1);
  334. }
  335.  
  336. /*
  337.  * SUN_draw
  338.  *
  339.  *    draws a line from the current graphics position to (x, y).
  340.  *
  341.  * Note: (0, 0) is defined as the top left of the window on a sun (easy
  342.  * to forget).
  343.  */
  344. SUN_draw(x, y)
  345.     int    x, y;
  346. {
  347.     pw_vector(pw, vdevice.cpVx, vdevice.sizeSy - vdevice.cpVy, x, vdevice.sizeSy - y, PIX_SRC | PIX_COLOR(COL(colour)), COL(colour));
  348. }
  349.  
  350. /*
  351.  * SUN_getkey
  352.  *
  353.  *    grab a character from the keyboard.
  354.  */
  355. int
  356. SUN_getkey()
  357. {
  358.     Event    event;
  359.  
  360.     do {
  361.         while ((input_readevent(wfd, &event) < 0) && (errno == EWOULDBLOCK))
  362.         ;    /* Nothing to read - wait for something */
  363.         
  364.     } while (!event_is_ascii(&event));    /* Wait for a key press */
  365.  
  366.     return(event_action(&event));
  367. }
  368.  
  369. /*
  370.  * SUN_checkkey
  371.  *
  372.  *    Check if a keyboard key has been hit. If so return it.
  373.  */
  374.  
  375. int
  376. SUN_checkkey()
  377. {
  378.     Event    event;
  379.     
  380.     if (input_readevent(wfd, &event) < 0) {
  381.         if (errno == EWOULDBLOCK) {
  382.             return(0);
  383.         } else {
  384.             perror("SUN_checkkey, input_readevent");
  385.             exit(1);
  386.         }
  387.     } else if (event_is_ascii(&event))
  388.         return(event_action(&event));
  389.  
  390.     return(0);
  391. }
  392.         
  393.  
  394. /*
  395.  * SUN_locator
  396.  *
  397.  *    return the window location of the cursor, plus which mouse button,
  398.  * if any, is been pressed.
  399.  */
  400. int
  401. SUN_locator(wx, wy)
  402.     int    *wx, *wy;
  403. {
  404.     int    but;
  405.     Event    event;
  406.     
  407.     but = 0;
  408.  
  409.     *wx = win_get_vuid_value(wfd, LOC_X_ABSOLUTE);
  410.     *wy = (int)vdevice.sizeSy - win_get_vuid_value(wfd, LOC_Y_ABSOLUTE);
  411.  
  412.     /* This used to work under 4.0 but not longer ..... Maybe
  413.      * SUN don't want us to use sunview anymore?
  414.     if (win_get_vuid_value(wfd, BUT(1)))
  415.         but |= 1;
  416.  
  417.     if (win_get_vuid_value(wfd, BUT(2)))
  418.         but |= 2;
  419.  
  420.     if (win_get_vuid_value(wfd, BUT(3)))
  421.         but |= 3;
  422.      */
  423.  
  424.  
  425.     if (input_readevent(wfd, &event) < 0) {
  426.         if (errno == EWOULDBLOCK) {
  427.             return(0);
  428.         } else {
  429.             perror("SUN_locator, input_readevent");
  430.             exit(1);
  431.         }
  432.     } else {
  433.         if (event_is_down(&event)) {
  434.             if (event_action(&event) == MS_LEFT)
  435.                 but |= 1;
  436.             if (event_action(&event) == MS_MIDDLE)
  437.                 but |= 2;
  438.             if (event_action(&event) == MS_RIGHT)
  439.                 but |= 4;
  440.         }
  441.     }
  442.  
  443.     return(but);
  444. }
  445.  
  446. /*
  447.  * SUN_clear
  448.  *
  449.  *    Clear the screen to current colour
  450.  */
  451. SUN_clear()
  452. {
  453.     int    x[4], y[4];
  454.  
  455.     if (vdevice.maxVx != vdevice.sizeSx
  456.        || vdevice.maxVy != vdevice.sizeSy
  457.        || vdevice.minVx != 0
  458.        || vdevice.minVy != 0) {
  459.         x[0] = x[3] = vdevice.minVx;
  460.         y[0] = y[1] = vdevice.maxVy;
  461.         y[2] = y[3] = vdevice.minVy;
  462.         x[1] = x[2] = vdevice.maxVx;
  463.  
  464.         SUN_fill(4, x, y);
  465.     } else {
  466.         pw_writebackground(pw, 0, 0, w, h, PIX_SRC | PIX_COLOR(COL(colour)) | PIX_DONTCLIP);
  467.     }
  468. }
  469.  
  470. /*
  471.  * SUN_color
  472.  *
  473.  *    set the current drawing color index.
  474.  */
  475. SUN_color(ind)
  476.         int    ind;
  477. {
  478.     colour = ind;
  479. }
  480.  
  481. /*
  482.  * SUN_mapcolor
  483.  *
  484.  *    change index i in the color map to the appropriate r, g, b, value.
  485.  */
  486. SUN_mapcolor(i, r, g, b)
  487.     int    i;
  488.     int    r, g, b;
  489. {
  490.     int    j;
  491.  
  492.     if (i >= 255 || vdevice.depth == 1)
  493.         return(-1);
  494.  
  495.     fr[i] = (u_char)r;
  496.     fg[i] = (u_char)g;
  497.     fb[i] = (u_char)b;
  498.  
  499.     if (i > 15)
  500.         usememory = 1;
  501.     else {
  502.         defred[i] = r;
  503.         defgreen[i] = g;
  504.         defblue[i] = b;
  505.  
  506.         for (j = 0; j < CMAPSIZE; j++) {
  507.             fr[i] = defred[j & 0x0f];
  508.             fg[i] = defgreen[j & 0x0f];
  509.             fb[i] = defblue[j & 0x0f];
  510.  
  511.             br[i] = defred[(j & 0xf0) >> 4];
  512.             bg[i] = defgreen[(j & 0xf0) >> 4];
  513.             bb[i] = defblue[(j & 0xf0) >> 4];
  514.         }
  515.     }
  516.  
  517.     /*
  518.      * gaurantee that background and forground differ
  519.      */
  520.     fr[255] = (u_char)~fr[0];
  521.     fg[255] = (u_char)~fg[0];
  522.     fb[255] = (u_char)~fb[0];
  523.  
  524.     br[255] = (u_char)~br[0];
  525.     bg[255] = (u_char)~bg[0];
  526.     bb[255] = (u_char)~bb[0];
  527.  
  528.     pw_putcolormap(pw, 0, CMAPSIZE, red, green, blue);
  529. }
  530.     
  531. /*
  532.  * SUN_font
  533.  *
  534.  *   Set up a hardware font. Return 1 on success 0 otherwise.
  535.  *
  536.  */
  537. SUN_font(fontfile)
  538.         char    *fontfile;
  539. {
  540.     char    name[BUFSIZ];
  541.  
  542.     if (font_id != (Pixfont *)NULL)
  543.         pf_close(font_id);
  544.  
  545.     if ((font_id = pf_open(fontfile)) == NULL)
  546.         if (*fontfile != '/') {
  547.             strcpy(name, STDFONTDIR);
  548.             strcat(name, fontfile);
  549.             if ((font_id = pf_open(name)) == NULL)
  550.                 return(0);
  551.         } else 
  552.             return(0);
  553.  
  554.     vdevice.hheight = font_id->pf_defaultsize.y;
  555.     vdevice.hwidth = font_id->pf_defaultsize.x;
  556.  
  557.     return(1);
  558. }
  559.  
  560. /* 
  561.  * SUN_char
  562.  *
  563.  *     outputs one char - is more complicated for other devices
  564.  */
  565. SUN_char(c)
  566.     char    c;
  567. {
  568.     char    *s = " ";
  569.  
  570.     s[0] = c;
  571.     pw_ttext(pw, vdevice.cpVx, (int)(vdevice.sizeSy - vdevice.cpVy), PIX_SRC | PIX_COLOR(COL(colour)), font_id, s);
  572. }
  573.  
  574. /*
  575.  * SUN_string
  576.  *
  577.  *    Display a string at the current drawing position.
  578.  */
  579. SUN_string(s)
  580.         char    s[];
  581. {
  582.     pw_ttext(pw, vdevice.cpVx, (int)(vdevice.sizeSy - vdevice.cpVy), PIX_SRC | PIX_COLOR(COL(colour)), font_id, s);
  583. }
  584.  
  585. /*
  586.  * SUN_fill
  587.  *
  588.  *    fill a polygon
  589.  */
  590. SUN_fill(n, x, y)
  591.     int    n, x[], y[];
  592. {
  593.     struct    pr_pos    vlist[128];
  594.     int    i, npnts;
  595.  
  596.     if (n > 128)
  597.         verror("vogl: more than 128 points in a polygon");
  598.  
  599.     npnts = n;
  600.  
  601.     for (i = 0; i < n; i++) {
  602.         vlist[i].x = x[i];
  603.         vlist[i].y = vdevice.sizeSy - y[i];
  604.     }
  605.  
  606.     pw_polygon_2(pw, 0, 0, 1, &npnts, vlist, PIX_SRC | PIX_COLOR(COL(colour)) | PIX_DONTCLIP, (Pixwin *)NULL, 0, 0);
  607.  
  608.     vdevice.cpVx = x[n-1];
  609.     vdevice.cpVy = y[n-1];
  610. }
  611.  
  612. /*
  613.  * SUN_backb
  614.  *
  615.  *    swap to memory only drawing (backbuffer) - a little slow but it
  616.  * works on everything. Where we can, we use the frame buffer.
  617.  */
  618. SUN_backb()
  619. {
  620.     int    mask = 0xff;
  621.  
  622.     if (vdevice.depth == 1 || usememory) {
  623.         if (vdevice.depth > 1)
  624.             pw_putattributes(pw, &mask);
  625.  
  626.         if (backb == (Pixrect *)NULL) {
  627.             if ((backb = mem_create((int)vdevice.sizeSx, (int)vdevice.sizeSy, vdevice.depth)) == (Pixrect *)NULL)
  628.                 return(-1);
  629.         }
  630.  
  631.         if (pw->pw_prretained == backb)
  632.             pw->pw_prretained = frontb;
  633.         else
  634.             pw->pw_prretained = backb;
  635.  
  636.         pw_batch_on(pw);
  637.     } else {
  638.         pw_getattributes(pw, &mask);
  639.         if (mask == bmask) {
  640.             red = fr;
  641.             green = fg;
  642.             blue = fb;
  643.             pw_putattributes(pw, &fmask);
  644.         } else {
  645.             red = br;
  646.             green = bg;
  647.             blue = bb;
  648.             pw_putattributes(pw, &bmask);
  649.         }
  650.  
  651.         pw_setcmsname(pw, "vogl");
  652.         pw_putcolormap(pw, 0, CMAPSIZE, red, green, blue);
  653.     }
  654.  
  655.     return(0);
  656. }
  657.  
  658. /*
  659.  * SUN_swapb
  660.  *
  661.  *    swap the front and back buffers.
  662.  */
  663. SUN_swapb()
  664. {
  665.     int    mask = 0xff;
  666.  
  667.     if (vdevice.depth == 1 || usememory) {
  668.         if (vdevice.depth > 1)
  669.             pw_putattributes(pw, &mask);
  670.  
  671.         if (vdevice.inbackbuffer) {
  672.             pw_batch_off(pw);
  673.             if (pw->pw_prretained == backb)
  674.                 pw->pw_prretained = frontb;
  675.             else
  676.                 pw->pw_prretained = backb;
  677.             pw_batch_on(pw);
  678.         } else {
  679.             if (backb == (Pixrect *)NULL) {
  680.                 if ((backb = mem_create((int)vdevice.sizeSx, (int)vdevice.sizeSy, vdevice.depth)) == (Pixrect *)NULL)
  681.                     return(-1);
  682.             }
  683.  
  684.             if (pw->pw_prretained == backb)
  685.                 pw->pw_prretained = frontb;
  686.             else
  687.                 pw->pw_prretained = backb;
  688.         }
  689.     } else {
  690.  
  691.         pw_getattributes(pw, &mask);
  692.         if (mask == bmask) {
  693.             red = fr;
  694.             green = fg;
  695.             blue = fb;
  696.             if (vdevice.inbackbuffer)
  697.                 pw_putattributes(pw, &fmask);
  698.         } else {
  699.             red = br;
  700.             green = bg;
  701.             blue = bb;
  702.             if (vdevice.inbackbuffer)
  703.                 pw_putattributes(pw, &bmask);
  704.         }
  705.  
  706.         pw_putcolormap(pw, 0, CMAPSIZE, red, green, blue);
  707.     }
  708.  
  709.     return(0);
  710. }
  711.  
  712. /*
  713.  * SUN_frontb
  714.  *
  715.  *    draw in the front buffer
  716.  */
  717. SUN_frontb()
  718. {
  719.     int    mask;
  720.  
  721.     if (vdevice.depth == 1 || usememory)
  722.         pw_batch_off(pw);
  723.     else {
  724.         if (vdevice.inbackbuffer) {
  725.             mask = 0xff;
  726.             pw_putattributes(pw, &mask);
  727.         }
  728.     }
  729. }
  730.  
  731. /*
  732.  * the device entry
  733.  */
  734. static DevEntry sundev = {
  735.     "sun",
  736.     "screen.b.16",
  737.     "screen.b.12",
  738.     SUN_backb,
  739.     SUN_char,
  740.     SUN_checkkey,
  741.     SUN_clear,
  742.     SUN_color,
  743.     SUN_draw,
  744.     SUN_exit,
  745.     SUN_fill,
  746.     SUN_font,
  747.     SUN_frontb,
  748.     SUN_getkey,
  749.     SUN_init,
  750.     SUN_locator,
  751.     SUN_mapcolor,
  752.     SUN_string,
  753.     SUN_swapb
  754. };
  755.  
  756. /*
  757.  * _SUN_devcpy
  758.  *
  759.  *    copy the sun device into vdevice.dev.
  760.  */
  761. _SUN_devcpy()
  762. {
  763.     vdevice.dev = sundev;
  764. }
  765.